#include "admin/client/RouteInfoDownloader.h"
#include "RequestBuilder.h"


namespace zeroplus::mq::admin
{
    RouteInfoDownloader::RouteInfoDownloader(std::string uri)
    {
        client_ = std::make_unique<ClientNode>(uri);
    }

    RouteInfoDownloader::~RouteInfoDownloader()
    {
    }

    routeinfo::ClusterInfo RouteInfoDownloader::QueryBrokerClusterInfo()
    {
        routeinfo::ClusterInfo clusterInfo;
        while (true)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(5000));
            transport::QueryBrokerClusterInfoResponse response = SendQueryBrokerClusterInfoRequest();
            clusterInfo = response.cluster_info();
            if (response.code() == transport::ResponseCode::SUCCESS)
            {
                break;
            }
        }
        PrintClusterInfo(clusterInfo);
        return clusterInfo;
    }

    transport::QueryBrokerClusterInfoResponse RouteInfoDownloader::SendQueryBrokerClusterInfoRequest()
    {
        LOG_DEBUG("发送路由注册请求");
        transport::QueryBrokerClusterInfoRequest request;
        request.set_msg("QueryAll");

        RequestBuilder<transport::RequestCode::QUERY_BROKER_CLUSTER_INFO,
                       transport::QueryBrokerClusterInfoRequest,
                       transport::QueryBrokerClusterInfoResponse>
            builder(client_);
        auto [responseCode, response] = builder.InvokeSync(request);
        return response;
    }

    void RouteInfoDownloader::PrintClusterInfo(const routeinfo::ClusterInfo &clusterInfo)
    {
        std::stringstream ss;
        // 打印 broker_addr_table
        ss << "  【Broker Address Table】:\n";
        for (const auto &entry : clusterInfo.broker_addr_table())
        {
            ss << "    Cluster Name: " << entry.second.cluster_name() << "\n";
            ss << "     Broker Name: " << entry.second.broker_name() << "\n";
            ss << "     Broker Addr: " << entry.second.broker_addrs().find(BrokerState::MASTER)->second << "\n";
        }

        // 打印 cluster_addr_table
        ss << "  【Cluster Address Table】:\n";
        for (const auto &entry : clusterInfo.cluster_addr_table())
        {
            ss << "    Cluster Name: " << entry.first << "\n";
            ss << "    Broker Names: [";
            for (int i = 0; i < entry.second.broker_data_set_size(); ++i)
            {
                ss << entry.second.broker_data_set(i);
                if (i < entry.second.broker_data_set_size() - 1)
                {
                    ss << ", ";
                }
            }
            ss << "]\n";
        }

        LOG_DEBUG("ClusterInfo:\n%s", ss.str().c_str());
    }
}
